Rescue and log email sending errors

Andrew Cantino 9 ans auparavant
Parent
Commettre
c436315826

+ 19 - 10
app/models/agents/email_agent.rb

@@ -37,19 +37,28 @@ module Agents
37 37
       }
38 38
     end
39 39
 
40
+    def working?
41
+      received_event_without_error?
42
+    end
43
+
40 44
     def receive(incoming_events)
41 45
       incoming_events.each do |event|
42 46
         recipients(event.payload).each do |recipient|
43
-          log "Sending mail to #{recipient} with event #{event.id}"
44
-          SystemMailer.send_message(
45
-            to: recipient,
46
-            from: interpolated(event)['from'],
47
-            subject: interpolated(event)['subject'],
48
-            headline: interpolated(event)['headline'],
49
-            body: interpolated(event)['body'],
50
-            content_type: interpolated(event)['content_type'],
51
-            groups: [present(event.payload)]
52
-          ).deliver_later
47
+          begin
48
+            SystemMailer.send_message(
49
+              to: recipient,
50
+              from: interpolated(event)['from'],
51
+              subject: interpolated(event)['subject'],
52
+              headline: interpolated(event)['headline'],
53
+              body: interpolated(event)['body'],
54
+              content_type: interpolated(event)['content_type'],
55
+              groups: [present(event.payload)]
56
+            ).deliver_now
57
+            log "Sent mail to #{recipient} with event #{event.id}"
58
+          rescue => e
59
+            error("Error sending mail to #{recipient} with event #{event.id}: #{e.message}")
60
+            raise
61
+          end
53 62
         end
54 63
       end
55 64
     end

+ 18 - 9
app/models/agents/email_digest_agent.rb

@@ -32,6 +32,10 @@ module Agents
32 32
       }
33 33
     end
34 34
 
35
+    def working?
36
+      received_event_without_error?
37
+    end
38
+
35 39
     def receive(incoming_events)
36 40
       incoming_events.each do |event|
37 41
         self.memory['queue'] ||= []
@@ -46,15 +50,20 @@ module Agents
46 50
         ids = self.memory['events'].join(",")
47 51
         groups = self.memory['queue'].map { |payload| present(payload) }
48 52
         recipients.each do |recipient|
49
-          log "Sending digest mail to #{recipient} with events [#{ids}]"
50
-          SystemMailer.send_message(
51
-            to: recipient,
52
-            from: interpolated['from'],
53
-            subject: interpolated['subject'],
54
-            headline: interpolated['headline'],
55
-            content_type: interpolated['content_type'],
56
-            groups: groups
57
-          ).deliver_later
53
+          begin
54
+            SystemMailer.send_message(
55
+              to: recipient,
56
+              from: interpolated['from'],
57
+              subject: interpolated['subject'],
58
+              headline: interpolated['headline'],
59
+              content_type: interpolated['content_type'],
60
+              groups: groups
61
+            ).deliver_now
62
+            log "Sent digest mail to #{recipient} with events [#{ids}]"
63
+          rescue => e
64
+            error("Error sending digest mail to #{recipient} with events [#{ids}]: #{e.message}")
65
+            raise
66
+          end
58 67
         end
59 68
         self.memory['queue'] = []
60 69
         self.memory['events'] = []

+ 16 - 0
spec/models/agents/email_agent_spec.rb

@@ -40,6 +40,21 @@ describe Agents::EmailAgent do
40 40
       expect(get_message_part(ActionMailer::Base.deliveries.first, /plain/).strip).to eq("hi!\n  data: Something you should know about")
41 41
     end
42 42
 
43
+    it "logs and re-raises any mailer errors" do
44
+      event1 = Event.new
45
+      event1.agent = agents(:bob_rain_notifier_agent)
46
+      event1.payload = { :message => "hi!", :data => "Something you should know about" }
47
+      event1.save!
48
+
49
+      mock(SystemMailer).send_message(anything) { raise Net::SMTPAuthenticationError.new("Wrong password") }
50
+
51
+      expect {
52
+        Agents::EmailAgent.async_receive(@checker.id, [event1.id])
53
+      }.to raise_error(/Wrong password/)
54
+
55
+      expect(@checker.logs.last.message).to match(/Error sending mail .* Wrong password/)
56
+    end
57
+
43 58
     it "can receive complex events and send them on" do
44 59
       stub_request(:any, /wunderground/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
45 60
       stub.any_instance_of(Agents::WeatherAgent).is_tomorrow?(anything) { true }
@@ -75,6 +90,7 @@ describe Agents::EmailAgent do
75 90
       expect(get_message_part(ActionMailer::Base.deliveries.last, /plain/).strip).to match(/\A\s*<strong>rain\!<\/strong>\s*\z/)
76 91
       expect(get_message_part(ActionMailer::Base.deliveries.last, /html/).strip).to match(/<body>\s*<strong>rain\!<\/strong>\s*<\/body>/)
77 92
     end
93
+
78 94
     it "can take content type option to set content type of email sent" do
79 95
       @checker.update_attributes :options => @checker.options.merge({
80 96
         'content_type' => 'text/plain'

+ 17 - 0
spec/models/agents/email_digest_agent_spec.rb

@@ -59,6 +59,23 @@ describe Agents::EmailDigestAgent do
59 59
       expect(@checker.reload.memory[:queue]).to be_empty
60 60
     end
61 61
 
62
+    it "logs and re-raises mailer errors" do
63
+      mock(SystemMailer).send_message(anything) { raise Net::SMTPAuthenticationError.new("Wrong password") }
64
+
65
+      @checker.memory[:queue] = [{ :data => "Something you should know about" }]
66
+      @checker.memory[:events] = [1]
67
+      @checker.save!
68
+
69
+      expect {
70
+        Agents::EmailDigestAgent.async_check(@checker.id)
71
+      }.to raise_error(/Wrong password/)
72
+
73
+      expect(@checker.reload.memory[:events]).not_to be_empty
74
+      expect(@checker.reload.memory[:queue]).not_to be_empty
75
+
76
+      expect(@checker.logs.last.message).to match(/Error sending digest mail .* Wrong password/)
77
+    end
78
+
62 79
     it "can receive complex events and send them on" do
63 80
       stub_request(:any, /wunderground/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
64 81
       stub.any_instance_of(Agents::WeatherAgent).is_tomorrow?(anything) { true }